//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

use std::path::PathBuf;

use serde::{Deserialize, Serialize};
use tauri::{
    plugin::{Plugin, Result as PluginResult},
    AppHandle, Invoke, PageLoadPayload, Runtime, Window,
};
use tokio::fs;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct ProjectLinkInfo {
    pub yaml_content: String,
}

#[tauri::command]
async fn get_link_info(git_path: String) -> Result<ProjectLinkInfo, String> {
    //检查是否是git目录
    let mut base_path = PathBuf::from(&git_path);
    base_path.push(".git");
    if base_path.exists() == false || base_path.is_dir() == false {
        return Err("not git repo".into());
    }
    let mut cfg_path = PathBuf::from(&git_path);
    cfg_path.push(".linksaas.yml");
    if cfg_path.exists() == false {
        return Ok(ProjectLinkInfo {
            yaml_content: "".into(),
        });
    }
    let yaml_content = fs::read_to_string(&cfg_path).await;
    if yaml_content.is_err() {
        return Err(yaml_content.err().unwrap().to_string());
    }
    let mut post_commit_path = base_path;
    post_commit_path.push("hooks");
    post_commit_path.push("post-commit");
    return Ok(ProjectLinkInfo {
        yaml_content: yaml_content.unwrap(),
    });
}

#[tauri::command]
async fn set_link_info(
    git_path: String,
    project_id: String,
) -> Result<(), String> {
    //检查是否是git目录
    let mut base_path = PathBuf::from(&git_path);
    base_path.push(".git");
    if base_path.exists() == false || base_path.is_dir() == false {
        return Err("not git repo".into());
    }
    //创建.linksaas.yml
    let mut cfg_path = PathBuf::from(&git_path);
    cfg_path.push(".linksaas.yml");

    let yml_content = format!("project_id: \"{}\"", &project_id);
    if let Err(err) = fs::write(&cfg_path, yml_content.as_bytes()).await {
        return Err(err.to_string());
    }
    Ok(())
}

pub struct ProjectToolApiPlugin<R: Runtime> {
    invoke_handler: Box<dyn Fn(Invoke<R>) + Send + Sync + 'static>,
}

impl<R: Runtime> ProjectToolApiPlugin<R> {
    pub fn new() -> Self {
        Self {
            invoke_handler: Box::new(tauri::generate_handler![get_link_info, set_link_info]),
        }
    }
}

impl<R: Runtime> Plugin<R> for ProjectToolApiPlugin<R> {
    fn name(&self) -> &'static str {
        "project_tool_api"
    }
    fn initialization_script(&self) -> Option<String> {
        None
    }

    fn initialize(&mut self, _app: &AppHandle<R>, _config: serde_json::Value) -> PluginResult<()> {
        Ok(())
    }

    fn created(&mut self, _window: Window<R>) {}

    fn on_page_load(&mut self, _window: Window<R>, _payload: PageLoadPayload) {}

    fn extend_api(&mut self, message: Invoke<R>) {
        (self.invoke_handler)(message)
    }
}
